03. Updating a Todo Item: Part II

Defining the handler for the route

ND004 C01 L07 03.3 Update Todo Item Walk-Through

Fixing the ordering

ND004 C01 L07 03.4 Update Todo Item Walk-Through

We're done with update!

Next up: adding the ability to delete To-Do items in our app.

Final Code

app.py

@app.route('/todos/<todo_id>/set-completed', methods=['POST'])
def set_completed_todo(todo_id):
  try:
    completed = request.get_json()['completed']
    print('completed', completed)
    todo = Todo.query.get(todo_id)
    todo.completed = completed
    db.session.commit()
  except:
    db.session.rollback()
  finally:
    db.session.close()
  return redirect(url_for('index'))

index.html

<html>
  <head>
    <title>Todo App</title>
    <style>
      .hidden {
        display: none;
      }
      ul {
        list-style: none;
        padding: 0;
        margin: 0;
        width: 300px;
      }
      li {
        clear: both;
      }
      li button {
        -webkit-appearance: none;
        border: none;
        outline: none;
        color: red;
        float: right;
        cursor: pointer;
        font-size: 20px;
      }
      .lists-wrapper, .todos-wrapper {
        display: inline-block;
        vertical-align: top;
      }
    </style>
  </head>
  <body>
    <div class="lists-wrapper">
      <ul id="lists">
        {% for list in lists %}
        <li>
          <a href="/lists/{{ list.id }}">
            {{ list.name }}
          </a>
        </li>
        {% endfor %}
      </ul>
    </div>
    <div class="todos-wrapper">
      <h4>{{ active_list.name }}</h4>
      <form id="form">
        <input type="text" id="description" name="description" />
        <input type="submit" value="Create" />
      </form>
      <div id="error" class="hidden">Something went wrong!</div>
      <ul id="todos">
        {% for todo in todos %}
        <li>
          <input class="check-completed" data-id="{{ todo.id }}" type="checkbox" {% if todo.completed %} checked {% endif %} />
          {{ todo.description }}
        </li>
        {% endfor %}
      </ul>
    </div>
    <script>
      const checkboxes = document.querySelectorAll('.check-completed');
      for (let i = 0; i < checkboxes.length; i++) {
        const checkbox = checkboxes[i];
        checkbox.onchange = function(e) {
          const newCompleted = e.target.checked;
          const todoId = e.target.dataset['id'];
          fetch('/todos/' + todoId + '/set-completed', {
            method: 'POST',
            body: JSON.stringify({
              'completed': newCompleted
            }),
            headers: {
              'Content-Type': 'application/json'
            }
          })
          .then(function() {
            document.getElementById('error').className = 'hidden';
          })
          .catch(function() {
            document.getElementById('error').className = '';
          })
        }
      }
      document.getElementById('form').onsubmit = function(e) {
        e.preventDefault();
        fetch('/todos/create', {
          method: 'POST',
          body: JSON.stringify({
            'description': document.getElementById('description').value
          }),
          headers: {
            'Content-Type': 'application/json'
          }
        })
        .then(function(response) {
          return response.json();
        })
        .then(function(jsonResponse) {
          console.log(jsonResponse);
          const liItem = document.createElement('LI');
          liItem.innerHTML = jsonResponse['description'];
          document.getElementById('todos').appendChild(liItem);
          document.getElementById('error').className = 'hidden';
        })
        .catch(function() {
          document.getElementById('error').className = '';
        })
      }
    </script>
  </body>
</html>